package com.example.demo.util;

import com.itextpdf.text.*;
import com.itextpdf.text.List;
import com.itextpdf.text.pdf.*;
import org.apache.commons.lang3.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by zhanglei on 2024/3/16.
 */
public class PdfUtils {

    /**
     * 字体存放的跟路径，默认为'C:\Windows\Fonts\'
     */
    private static final String FONT_PATH = "C:\\Windows\\Fonts\\";

    /**
     * 纸张大小
     */
    private static Rectangle RECTANGLE = PageSize.A4;

    /**
     * 设置字体默认值
     *
     * @return
     * @throws DocumentException
     * @throws IOException
     */
    private static BaseFont createBaseFont(String fontName) throws DocumentException, IOException {
        // 默认为宋体
        if (fontName == null) {
            fontName = "simsun.ttc";
//            fontName = "seguisym.ttf";

        }
        String fontPre = fontName.substring(fontName.lastIndexOf(".") + 1);
        if (fontPre.equals("ttc")) {
            // ttc格式的字体需要加上后缀
            fontName = fontName + ",0";
        }
        String font = FONT_PATH + fontName;
        return BaseFont.createFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//        return BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    }

    /**
     * 设置字体
     *
     * @return
     */
    public static Font setFont() {
        return setFont(null, null, null, null);
    }

    public static Font setFont(Integer fontSize) {
        return setFont(null, fontSize, null, null);
    }

    public static Font setFont(Integer fontSize, BaseColor fontColor) {
        return setFont(null, fontSize, null, fontColor);
    }

    /**
     * @param fontName  字体名称 默认宋体
     * @param fontSize  字体大小 默认12号
     * @param fontStyle 字体样式
     * @param fontColor 字体颜色 默认黑色
     * @return
     */
    public static Font setFont(String fontName, Integer fontSize, Integer fontStyle, BaseColor fontColor) {
        try {
            BaseFont baseFont = createBaseFont(fontName);
            Font font = new Font(baseFont);
            if (fontSize != null) {
                font.setSize(fontSize);
            }
            if (fontStyle != null) {
                font.setStyle(fontStyle);
            }
            if (fontColor != null) {
                font.setColor(fontColor);
            }
            return font;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("设置字体失败！");
        }
    }

    /**
     * 创建pdf文档
     *
     * @param response
     * @param fileName
     * @return
     */
    public static Document createDocument(HttpServletResponse response, String fileName) {
        /*try {
            response.reset();
            response.setHeader("Content-Type", "application/pdf-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        // 设置大小
        RECTANGLE = PageSize.A4;
        return new Document(RECTANGLE, 50, 50, 80, 50);
    }

    /**
     * 绘制标题
     *
     * @param font
     * @param titleName
     * @return
     */
    public static Paragraph setParagraph(Font font, String titleName) {
        Paragraph paragraph = new Paragraph(titleName, font);
        //设置文字居中
        paragraph.setAlignment(Element.ALIGN_CENTER);
        //行间距
        paragraph.setLeading(5f);
        //设置段落上空白
        paragraph.setSpacingBefore(-20f);
        //设置段落下空白
        paragraph.setSpacingAfter(15f);
        return paragraph;
    }


    private static PdfPTable createTable(float[] widths) {
        PdfPTable table = new PdfPTable(widths);
        try {
            // 设置表格大小
            table.setTotalWidth(RECTANGLE.getWidth() - 100);

            table.setLockedWidth(true);
            // 居中
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            // 边框
            table.getDefaultCell().setBorder(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return table;
    }

    private static PdfPCell createCell(String value, Font font) {
        PdfPCell cell = new PdfPCell();
        // 水平、垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }

    /**
     * 给pdf添加图片水印
     *
     * @param waterMar
     * @param path     图片路径
     * @throws Exception
     */
    public static void addWater(PdfContentByte waterMar, String path) throws Exception {
        File file = new File(path);
        if (!file.exists()) {
            throw new RuntimeException("水印图片不存在！");
        }
        waterMar.beginText();

        PdfGState gs = new PdfGState();
        // 不透明度
        gs.setFillOpacity(0.2f);
        // 设置透明度
        waterMar.setGState(gs);
        // 设置对齐方式 内容 X坐标 Y坐标 旋转角度
        Image img = Image.getInstance(path);
        // 设置大小为200，并且居中
        float newWidth = 200f;
        float newHeight = 200f;
        img.scaleAbsolute(newWidth, newHeight);
        img.setAbsolutePosition((RECTANGLE.getWidth() - newWidth) / 2, (RECTANGLE.getHeight() - newHeight) / 2);

        waterMar.addImage(img);
        // 水印颜色
        waterMar.setColorFill(BaseColor.GRAY);

        // 关闭
        waterMar.endText();
        waterMar.stroke();
    }

    /**
     * 给pdf添加文字水印
     *
     * @param waterMar
     * @param text     水印文本
     * @param full     是否平铺
     * @throws Exception
     */
    public static void addWater(PdfContentByte waterMar, String text, boolean full) throws Exception {
        if (org.apache.commons.lang3.StringUtils.isEmpty(text)) {
            return;
        }
        waterMar.beginText();
        PdfGState gs = new PdfGState();
        // 不透明度
        gs.setFillOpacity(0.2f);
        int fontSize = 14;
        waterMar.setFontAndSize(createBaseFont(null), fontSize);
        // 设置透明度
        waterMar.setGState(gs);
        if (full) {
            // 设置对齐方式 内容 X坐标 Y坐标 旋转角度 '/6'目的是为了让宽存在6个水印
            for (int x = 50; x <= RECTANGLE.getWidth(); x += RECTANGLE.getWidth() / 4) {
                for (int y = 50; y <= RECTANGLE.getHeight(); y += RECTANGLE.getHeight() / 4) {
                    waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 45);
                }
            }
        } else {
            waterMar.showTextAligned(Element.ALIGN_RIGHT, text, (RECTANGLE.getWidth()) / 2, (RECTANGLE.getHeight()) / 2, 45);
        }
        // 水印颜色
        waterMar.setColorFill(BaseColor.GRAY);

        // 关闭
        waterMar.endText();
        waterMar.stroke();
    }

    /**
     * 添加图片
     *
     * @param document
     * @param imgPath
     * @param newWidth
     * @param newHeight
     * @throws IOException
     * @throws DocumentException
     */
    public static void addImg(Document document, String imgPath, float newWidth, float newHeight) throws IOException, DocumentException {
        Image img1 = Image.getInstance(imgPath);
        img1.setAbsolutePosition(50, RECTANGLE.getHeight() - 60);
        img1.scaleAbsolute(newWidth, newHeight);
        document.add(img1);
    }


    /**
     * 生成页眉
     *
     * @param pdfWriter
     * @param text
     */
    public static void addHeader(PdfWriter pdfWriter, String text) {
        ColumnText.showTextAligned(pdfWriter.getDirectContent(),
                Element.ALIGN_LEFT, new Paragraph(text, PdfUtils.setFont(10, BaseColor.GRAY)),
                50, RECTANGLE.getHeight() - 12, 0);
    }

    /**
     * 生成页码
     *
     * @param pdfWriter
     * @param document
     */
    public static void addPageNum(PdfWriter pdfWriter, Document document) {
        try {
            //创建一个两列的表格
            PdfPTable table = new PdfPTable(1);
            table.setTotalWidth(RECTANGLE.getWidth());
            //锁定列宽
            table.setLockedWidth(true);
            //设置每列宽度
            table.setWidths(new int[]{20});
            // 设置页码，字体大小为12号，灰色
            PdfPCell cell = new PdfPCell(new Phrase("—  " + document.getPageNumber() + "  —", PdfUtils.setFont(10, BaseColor.GRAY)));

            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.disableBorderSide(-1);
            table.addCell(cell);

            // 将页码写到距离pdf底部30px的位置
            table.writeSelectedRows(0, -1, 0, 30, pdfWriter.getDirectContent());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("设置页眉失败！");
        }
    }

    public static PdfPCell createCell(String value,Font font,int align,int colspan, int rowspan){

        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setPhrase(new Phrase(value,font));
        cell.setColspan(colspan);
        cell.setRowspan(rowspan);
        return cell;

    }

    public static PdfPHeaderCell createPdfPHeaderCell(String value,Font font,int align,int colspan, int rowspan){

        PdfPHeaderCell cell = new PdfPHeaderCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setPhrase(new Phrase(value,font));
        cell.setColspan(colspan);
        cell.setRowspan(rowspan);
        return cell;

    }

    public static PdfPCell createCell(String value,Font font,int align){

        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setPhrase(new Phrase(value,font));
        return cell;

    }

    public static PdfPCell createCell(String value,Font font,int align,int colspan,boolean boderFlag){

        PdfPCell cell = new PdfPCell();

        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

        cell.setHorizontalAlignment(align);

        cell.setColspan(colspan);

        cell.setPhrase(new Phrase(value,font));

        cell.setPadding(3.0f);

        if(!boderFlag){

            cell.setBorder(0);

            cell.setPaddingTop(15.0f);

            cell.setPaddingBottom(8.0f);

        }

        return cell;

    }

    public static void main(String[] args) throws Exception {

        File file = new File("D:\\text2.pdf");

        file.createNewFile();

        FileOutputStream fileOutputStream = new FileOutputStream(file);
//        BufferedOutputStream os = new BufferedOutputStream(fileOutputStream);

        // 1.设置输出的文件名称
        String fileName = "红字发票信息确认单.pdf";
        Font textfont = PdfUtils.setFont(10);
        Font timefont = PdfUtils.setFont(14);

        // 2.创建pdf文档，并且设置纸张大小为A4
        Document document = PdfUtils.createDocument(null, fileName);
        PdfWriter writer = PdfWriter.getInstance(document, fileOutputStream);


        // 3.设置事件(水印、页眉、logo)等
        NewPdfPageEventHelper helper = new NewPdfPageEventHelper();
        // 页码
        helper.setPageNum();
        // 开启回调事件
        writer.setPageEvent(helper);

        // 4.打开文档
        document.open();

        // 5.设置标题
        String titleName = "红字发票信息确认单";
        // 设置字体样式：黑体 20号 加粗 黑色
        Font titleFont = PdfUtils.setFont(null, 20, Font.BOLD, BaseColor.BLACK);
        Paragraph paragraph = PdfUtils.setParagraph(titleFont, titleName);


        // 6.设置表格
        // 设置表头字体样式：黑体 14号 加粗 黑色
        // 设置正文字体样式：12号

        PdfPTable table = createTable(new float[]{45,95,110,45,70,55,55});

        table.addCell(createCell("填开日期：2024年03月01日", timefont,Element.ALIGN_LEFT,7,false));
        table.addCell(createCell("销售方", textfont, Element.ALIGN_CENTER, 1, 2));
        table.addCell(createCell("纳税人名称（销方）", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("测试测试企业名称", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("购买方", textfont, Element.ALIGN_CENTER,1,2));
        table.addCell(createCell("纳税人名称（购方）", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("测试购方企业名称", textfont, Element.ALIGN_CENTER,2,1));

        table.addCell(createCell("统一社会信用代码/纳税人识别号（销方）", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("91440604MA52J0J10H", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("统一社会信用代码/纳税人识别号（购方）", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("911136587421536541", textfont, Element.ALIGN_CENTER,2,1));

        int num = 40;
        /*PdfPCell cell11 = new PdfPCell(getImage());
        // 水平、垂直居中
        cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell11.setHorizontalAlignment(Element.ALIGN_MIDDLE);
        cell11.setColspan(1);
        cell11.setRowspan(num+3);*/
        PdfPCell cell11 = createCell("开具\r\n红字\r\n发票\r\n确认\r\n信息\r\n内容", textfont, Element.ALIGN_CENTER, 1, num + 3);

        table.addCell(cell11);
        table.addCell(createCell("项目名称", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("数量", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("单价", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("金额", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("税率/征收率", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("税额", textfont, Element.ALIGN_CENTER));

        //明细
        BaseFont baseFont = createBaseFont(null);
        for(int i=0;i<num;i++){
            table.addCell(createCell("*蔬菜*豆芽"+i, textfont));
            table.addCell(createCell(i+"", textfont));
            String value = "1.234789046789";
            Font font = getFont(baseFont, value);
            PdfPCell cell = createCell(value, font);
            table.addCell(cell);

            table.addCell(createCell("1.2", textfont));
            table.addCell(createCell("0%", textfont));
            table.addCell(createCell("0.00", textfont));

        }
        table.addCell(createCell("合计", textfont));
        table.addCell(createCell("----", textfont));
        table.addCell(createCell("----", textfont));
        table.addCell(createCell("6.00", textfont));
        table.addCell(createCell("----", textfont));
        table.addCell(createCell("6.00", textfont));


        PdfPCell cell = new PdfPCell();
        // 水平、垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setColspan(6);
        cell.setRowspan(1);

        Paragraph para = new Paragraph(new Phrase("",textfont));
        // 添加文本和图片到段落
        para.add("一、录入方身份：\r\n");
        para.add("  1.销售方□☑  2.购买方□☑  \r\n");
        para.add("二、冲红原因：\r\n");
        para.add("  1.开票有误□☑  2.销货退回□☑  3.服务终止□☑  4.销售折让□☑  \r\n");
        para.add("三、对应蓝字发票抵扣增值税销项税额情况：\r\n");
        para.add(" 1.已抵扣□☑  2.未抵扣□☑  \r\n");
        para.add(" 对应蓝字发票的代码： 号码：");
        Chunk chunk1 = new Chunk("24442000000000071607\n");
        chunk1.setUnderline(0.8f, -1);
        para.add(chunk1);
        para.add("四、是否涉及数量（仅限成品油、机动车等业务填写）\r\n");
        para.add("  涉及销售数量□☑  仅涉及销售金额□☑  \r\n");
        para.add("\r\n");
        cell.addElement(para);
        table.addCell(cell);

        table.addCell(createCell("红字发票信息确认单编号", textfont, Element.ALIGN_CENTER));
        table.addCell(createCell("24442000000000071607", textfont, Element.ALIGN_LEFT,6,1));

        // 7.填充内容
        document.add(paragraph);
        document.add(table);

        // 关闭资源
        document.close();

    }




    public static PdfPTable getImage() throws Exception {


        PdfPTable datatable = new PdfPTable(1);
        int CellWidth[] = {10};
        datatable.setWidths(CellWidth);
        datatable.getDefaultCell().setBorder(1);

        PdfPHeaderCell cell = new PdfPHeaderCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_MIDDLE);
        cell.setBorder(0);
        Font textfont = PdfUtils.setFont(10);
        cell.setPhrase(new Phrase("文本",textfont));

        datatable.addCell(cell);
        datatable.setHeadersInEvent(true);
        cell.setPhrase(new Phrase("",textfont));
        datatable.addCell(cell);

        datatable.setHeaderRows(1);

        return datatable;
    }

    //获取字体大小
    private static Font getFont(BaseFont baseFont, String value) {
        int textBoxWidth = 45;
        int fontSize = 10;
        float textWidth = baseFont.getWidthPoint(value, fontSize);
        // 文本框高度只够写一行，并且文字宽度大于文本框宽度，则缩小字体
        while (textWidth > textBoxWidth) {
            fontSize--;
            textWidth = baseFont.getWidthPoint(value, fontSize);
        }
        return PdfUtils.setFont(fontSize);
    }






    /*public static void main(String[] args) throws Exception {

        File file = new File("D:\\text2.pdf");

        file.createNewFile();

        FileOutputStream fileOutputStream = new FileOutputStream(file);
        BufferedOutputStream os = new BufferedOutputStream(fileOutputStream);

        // 1.设置输出的文件名称
        String fileName = "考勤报表.pdf";

        // 2.创建pdf文档，并且设置纸张大小为A4
        Document document = PdfUtils.createDocument(null, fileName);
        PdfWriter writer = PdfWriter.getInstance(document, os);

        // 3.设置事件(水印、页眉、logo)等
        NewPdfPageEventHelper helper = new NewPdfPageEventHelper();
        // 水印
//        helper.setImageWaterWater("C:\\Users\\LiGezZ\\Desktop\\java.png");
//        helper.setTextWaterWater("这 是 文 字 水 印", true);
        // logo
//        helper.setLogo("C:\\Users\\LiGezZ\\Desktop\\logo.png", 80, 40);
        // 页眉
        helper.setHeader("xxxxx科技股份有限公司");
        // 页码
        helper.setPageNum();
        // 开启回调事件
        writer.setPageEvent(helper);

        // 4.打开文档
        document.open();

        // 5.设置标题
        String titleName = "这 个 是 标 题";
        // 设置字体样式：黑体 20号 加粗 红色
        Font titleFont = PdfUtils.setFont("simhei.ttf", 20, Font.BOLD, BaseColor.RED);
        Paragraph paragraph = PdfUtils.setParagraph(titleFont, titleName);

        // 6.设置表格
        // 定义列名
        String[] title = {"姓名", "性别", "年龄", "地址"};
        // 获取列表数据
        // 设置表头字体样式：黑体 14号 加粗 黑色
        // 设置正文字体样式：12号
        Font headFont = PdfUtils.setFont("simhei.ttf", 12, Font.BOLD, BaseColor.BLACK);
        Font textFont = PdfUtils.setFont(12);
        java.util.List<User> dataList = getData();
        PdfPTable table = PdfUtils.setTable(headFont, textFont, title, dataList);
        // 7.填充内容
        document.add(paragraph);
        document.add(table);

        // 关闭资源
        document.close();

    }

    public static java.util.List<User> getData() {
        java.util.List<User> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            User user = new User();
            user.setName("名称-" + i);
            user.setAddress("地址-" + i);
            user.setAgx(20);
            user.setGender("男");

            list.add(user);
        }
        return list;
    }*/

}
